/*
 * Copyright (C) 2006-2007 Eskil Bylund
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

using System;

using Gtk;
using Glade;

namespace DCSharp.Gui
{
	public class MessageArea : VBox
	{
		private HBox hbox;
		private VBox vbox;

		private Image image;
		private Label primaryLabel;
		private Label secondaryLabel;

		private string primaryText;
		private string secondaryText;
		private MessageType messageType;

		private bool changingStyle;

		#region Constructors

		public MessageArea(string primaryText, string secondaryText,
			MessageType messageType) : base()
		{
			// Create the widgets
			hbox = new HBox(false, 6);
			hbox.StyleSet += OnStyleSet;
			hbox.SizeRequested += OnSizeRequested;
			PackStart(hbox, true, true, 0);

			image = new Image();
			image.IconSize = (int)IconSize.Menu;
			image.Yalign = 0;
			hbox.PackStart(image, false, true, 0);

			vbox = new VBox(false, 6);
			hbox.PackStart(vbox, true, true, 0);

			primaryLabel = new Label();
			primaryLabel.Selectable = true;
			primaryLabel.Xalign = 0;
			vbox.PackStart(primaryLabel, false, true, 0);

			secondaryLabel = new Label();
			secondaryLabel.Selectable = true;
			secondaryLabel.Xalign = 0;
			vbox.PackStart(secondaryLabel, false, true, 0);

			hbox.ShowAll();

			// Initialize
			AppPaintable = true;
			BorderWidth = 6;

			PrimaryText = primaryText;
			SecondaryText = secondaryText;
			MessageType = messageType;
		}

		#endregion

		#region Classes

		private class TipWindow : Gtk.Window
		{
			public TipWindow() : base(Gtk.WindowType.Popup) 
			{
				Name = "gtk-tooltips";
			}
		}

		#endregion

		#region Properties

		public string PrimaryText
		{
			get { return primaryText; }
			set
			{
				primaryText = value;
				primaryLabel.Markup = String.Format("<b>{0}</b>", primaryText);
				primaryLabel.Visible = primaryText != null;
			}
		}

		public string SecondaryText
		{
			get { return secondaryText; }
			set
			{
				secondaryText = value;
				secondaryLabel.Text = secondaryText;
				secondaryLabel.Visible = secondaryText != null;
			}
		}

		public MessageType MessageType
		{
			get { return messageType; }
			set
			{
				messageType = value;
				image.Visible = true;

				switch (messageType)
				{
					case MessageType.Error:
						image.Stock = Stock.DialogError;
						break;

					case MessageType.Info:
						image.Stock = Stock.DialogInfo;
						break;

					case MessageType.Question:
						image.Stock = Stock.DialogQuestion;
						break;

					case MessageType.Warning:
						image.Stock = Stock.DialogWarning;
						break;

					default:
						image.Visible = false;
						break;
				}
			}
		}

		public VBox VBox
		{
			get { return vbox; }
		}

		public HBox HBox
		{
			get { return hbox; }
		}

		#endregion

		#region Methods

		protected override bool OnExposeEvent(Gdk.EventExpose evnt)
		{
			Gtk.Style.PaintFlatBox(Style, GdkWindow, State, ShadowType.Out,
				evnt.Area, this, "tooltip", Allocation.X, Allocation.Y,
				Allocation.Width, Allocation.Height);

			return base.OnExposeEvent(evnt);
		}

		private void OnSizeRequested(object obj, SizeRequestedArgs args)
		{
			// FIXME: When the widget is shown or its size changes there are
			// drawing glitches. The hack below seems to work resonably well.
			GLib.Idle.Add(ForceRedraw);
			GLib.Timeout.Add(10, ForceRedraw);
		}

		private bool ForceRedraw()
		{
			QueueDraw();
			return false;
		}

		private void OnStyleSet(object obj, StyleSetArgs args)
		{
			if (changingStyle)
			{
				return;
			}

			Window window = new TipWindow();
			window.EnsureStyle();

			changingStyle = true;
			Style = window.Style.Copy();
			changingStyle = false;

			window.Destroy();
			QueueDraw();
		}

		#endregion
	}
}
